/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  							 script_target_type.h

	$Header: /heroes4/script_target_type.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( SCRIPT_TARGET_TYPE_H_INCLUDED )
#define SCRIPT_TARGET_TYPE_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <cassert>
#include <string>

#include "player_color.h"

enum t_script_context;

enum t_script_target_type
{
	k_script_target_stack,
	k_script_target_hero,
	k_script_target_army,
	k_script_target_town,
	k_script_target_player,

	k_script_target_type_count,
};

enum t_script_stack_target
{
	k_script_stack_target_this,
	k_script_stack_target_this_army,
	k_script_stack_target_garrison,
	k_script_stack_target_opposing_army,

	k_script_stack_target_count,
};

enum t_script_hero_target
{
	k_script_hero_target_this,
	k_script_hero_target_this_army_any,
	k_script_hero_target_garrison_any,
	k_script_hero_target_opposing_army_any,
	k_script_hero_target_this_army_most_powerful,
	k_script_hero_target_garrison_most_powerful,
	k_script_hero_target_opposing_army_most_powerful,
	k_script_hero_target_this_army_least_powerful,
	k_script_hero_target_garrison_least_powerful,
	k_script_hero_target_opposing_army_least_powerful,

	k_script_hero_target_count,
};

enum t_script_army_target
{
	k_script_army_target_this,
	k_script_army_target_garrison,
	k_script_army_target_opposing,

	k_script_army_target_count,
};

enum t_script_player_target
{
	k_script_player_target_owner,
	k_script_player_target_current,
	k_script_player_target_opposing,
	k_script_player_target_specific,

	k_script_player_target_count = k_script_player_target_specific + k_active_player_color_count,
};

enum t_old_script_player_target
{
	k_old_script_player_target_owner,
	k_old_script_player_target_opposing,
	k_old_script_player_target_specific,

	k_old_script_player_target_count = k_old_script_player_target_specific + k_active_player_color_count,
};

inline t_script_player_target translate( t_old_script_player_target target )
{
	if ( target > k_old_script_player_target_owner )
		return t_script_player_target( target + 1 );
	return t_script_player_target( target );
}

inline bool is_specific( t_script_player_target target )
{
	assert( target >= 0 && target < k_script_player_target_count );
	return		target >= k_script_player_target_specific
			&&	target < k_script_player_target_specific + k_active_player_color_count;
}

inline t_script_player_target get_player_target(
	t_player_color color )
{
	assert( color >= 0 && color < k_active_player_color_count );
	return t_script_player_target( k_script_player_target_specific + color );
}

inline t_player_color get_player_color( t_script_player_target target )
{
	assert(		target >= k_script_player_target_specific
			&&	target < k_script_player_target_specific + k_active_player_color_count );
	return t_player_color( target - k_script_player_target_specific );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool is_valid( t_script_context context, t_script_stack_target target );
bool is_valid( t_script_context context, t_script_hero_target target );
bool is_valid( t_script_context context, t_script_army_target target );
bool is_valid( t_script_context context, t_script_player_target target );

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------

template < typename t_target >
struct t_script_target_type_traits {};

#define DEFINE_SCRIPT_TARGET_TYPE_TRAITS( t_target, k_count_arg )	\
template <>															\
struct t_script_target_type_traits< t_target >						\
{																	\
	enum { k_count = k_count_arg };									\
}

DEFINE_SCRIPT_TARGET_TYPE_TRAITS( t_script_stack_target, k_script_stack_target_count );
DEFINE_SCRIPT_TARGET_TYPE_TRAITS( t_script_hero_target, k_script_hero_target_count );
DEFINE_SCRIPT_TARGET_TYPE_TRAITS( t_script_army_target, k_script_army_target_count );
DEFINE_SCRIPT_TARGET_TYPE_TRAITS( t_script_player_target, k_script_player_target_count );

#undef DEFINE_SCRIPT_TARGET_TYPE_TRAITS

#endif // !defined( SCRIPT_TARGET_TYPE_H_INCLUDED )
